package mm.util;

import java.io.StringReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

public class XMLUtils {
	
	private static final Log LOG=LogFactory.getLog(XMLUtils.class);

	public static Document readClassPath(String xmlPath, boolean needValidation) {
		Document doc = null;
		if(xmlPath==null){
			return doc;
		}
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		// no affect?
		docBuilderFactory.setValidating(needValidation);
        DocumentBuilder docBuilder;
		try {
			docBuilder = docBuilderFactory.newDocumentBuilder();
	        doc = docBuilder.parse(Thread.currentThread().getContextClassLoader().getResourceAsStream(xmlPath));
	        // for what?
	        doc.getDocumentElement().normalize ();
		} catch (Exception e) {
			LOG.error("Errors happened in parsing xml...", e);
		}
		return doc;
	}

	public static Document readFilePath(String xmlPath, boolean needValidation) {
		Document doc = null;
		if(xmlPath==null){
			return doc;
		}
		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
		// no affect?
		docBuilderFactory.setValidating(needValidation);
        DocumentBuilder docBuilder;
		try {
			docBuilder = docBuilderFactory.newDocumentBuilder();
	        doc = docBuilder.parse (new URL("file:"+xmlPath).openStream());
	        // for what?
	        doc.getDocumentElement ().normalize ();
		} catch (Exception e) {
			LOG.error("Errors happened in parsing xml...", e);
		}
		return doc;
	}
	
	public static boolean toBoolean(String in){
		if("false".equalsIgnoreCase(in)
				||"0".equalsIgnoreCase(in)
				||"no".equalsIgnoreCase(in))
			return false;
		else
			return true;
	}
	
	// TODO try encoding
	public static Document buildDocument(String xml) {
		try {
			DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder builder = factory.newDocumentBuilder();
	        return builder.parse(new InputSource(new StringReader(xml)));
		} catch (Exception e) {
			LOG.error("Errors happened in parsing xml...", e);
			return null;
		}
	}

	// TODO Upcase
	public static List<Map<String, Object>> describeTable(Element table) {
		List<Map<String, Object>> list=new ArrayList<Map<String, Object>>();
		NodeList trs = table.getElementsByTagName("tr");
		if(trs.getLength()<2)
			return list;
		NodeList ths = ((Element)trs.item(0)).getElementsByTagName("th");
		if(ths.getLength()<1)
			ths = ((Element)trs.item(0)).getElementsByTagName("td");
		List<String> keys=new ArrayList<String>();
		for(int i=0;i<ths.getLength();i++){
			Node th = ths.item(i);
			String key=th.getTextContent();
			keys.add(key);
		}
		for(int i=1;i<trs.getLength();i++){
			Node tr = trs.item(i);
			NodeList tds = ((Element)tr).getElementsByTagName("td");
			Map<String, Object> row=new HashMap<String, Object>();
			list.add(row);
			for(int j=0;j<tds.getLength();j++){
				Node td = tds.item(j);
				String key=keys.get(j);
				NodeList childNodes = td.getChildNodes();
				if(childNodes!=null&&childNodes.getLength()==1
						&&childNodes.item(0).getNodeName().equals("#text")){
					row.put(key, td.getTextContent());
				}else{
					row.put(key, childNodes);
				}
			}
		}
		return list;
	}

}
